<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件


if (!defined('__ROOT__')) {
    $_root = rtrim(dirname(rtrim($_SERVER['SCRIPT_NAME'], '/')), '/');
    define('__ROOT__', (('/' == $_root || '\\' == $_root) ? '' : $_root));
}
use \think\Db;
use \think\Loader;
use phpmailer\PHPMailer;
use app\common\model\User;
// 应用公共文件
/**
 * 获取ip
 * @dateTime 2016-05-12T17:39:35+0800
 * @return   [type]                   [description]
 */
function inge_get_ip()
{
    if (getenv('HTTP_CLIENT_IP')) {
        $ip = getenv('HTTP_CLIENT_IP');
    } else if (getenv('HTTP_X_FORWARDED_FOR')) {
        $ip = getenv('HTTP_X_FORWARDED_FOR');
    } else if (getenv('REMOTE_ADDR')) {
        $ip = getenv('REMOTE_ADDR');
    } else {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}
/**
 * 获取浏览器
 */
function inge_get_browser()
{
    $agent = $_SERVER["HTTP_USER_AGENT"];
    if (strpos($agent, 'MSIE') !== false || strpos($agent, 'rv:11.0')) //ie11判断
    {
        return "ie";
    } else if (strpos($agent, 'Firefox') !== false) {
        return "firefox";
    } else if (strpos($agent, 'Chrome') !== false) {
        return "chrome";
    } else if (strpos($agent, 'Opera') !== false) {
        return 'opera';
    } else if ((strpos($agent, 'Chrome') == false) && strpos($agent, 'Safari') !== false) {
        return 'safari';
    } else if (strpos($agent, 'MicroMessenger') !== false) {
        return 'weixin';
    } else {
        return 'unknown';
    }

}

/**
 * 获取浏览器版本号
 * @dateTime 2016-05-12T17:41:31+0800
 * @return   [type]                   [description]
 */
function inge_get_browser_ver()
{
    if (empty($_SERVER['HTTP_USER_AGENT'])) {
        //当浏览器没有发送访问者的信息的时候
        return 'unknow';
    }
    $agent = $_SERVER['HTTP_USER_AGENT'];
    if (preg_match('/MSIE\s(\d+)\..*/i', $agent, $regs)) {
        return $regs[1];
    } elseif (preg_match('/FireFox\/(\d+)\..*/i', $agent, $regs)) {
        return $regs[1];
    } elseif (preg_match('/Opera[\s|\/](\d+)\..*/i', $agent, $regs)) {
        return $regs[1];
    } elseif (preg_match('/Chrome\/(\d+)\..*/i', $agent, $regs)) {
        return $regs[1];
    } elseif ((strpos($agent, 'Chrome') == false) && preg_match('/Safari\/(\d+)\..*$/i', $agent, $regs)) {
        return $regs[1];
    } else {
        return 'unknow';
    }

}
/**
 * 获取用户系统
 * @dateTime 2016-05-12T17:39:48+0800
 * @return   [type]                   [description]
 */
function inge_get_os()
{
    $agent = $_SERVER['HTTP_USER_AGENT'];
    $os    = false;
    // var_dump($agent);
    if (preg_match('/win/i', $agent) && strpos($agent, '95')) {
        $os = 'Windows 95';
    } else if (preg_match('/win 9x/i', $agent) && strpos($agent, '4.90')) {
        $os = 'Windows ME';
    } else if (preg_match('/win/i', $agent) && preg_match('/98/i', $agent)) {
        $os = 'Windows 98';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.0/i', $agent)) {
        $os = 'Windows Vista';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.1/i', $agent)) {
        $os = 'Windows 7';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.2/i', $agent)) {
        $os = 'Windows 8';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 10.0/i', $agent)) {
        $os = 'Windows 10';
        #添加win10判断
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 5.1/i', $agent)) {
        $os = 'Windows XP';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 5/i', $agent)) {
        $os = 'Windows 2000';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt/i', $agent)) {
        $os = 'Windows NT';
    } else if (preg_match('/win/i', $agent) && preg_match('/32/i', $agent)) {
        $os = 'Windows 32';
    } else if (preg_match('/linux/i', $agent)) {
        $os = 'Linux';
    } else if (preg_match('/unix/i', $agent)) {
        $os = 'Unix';
    } else if (preg_match('/sun/i', $agent) && preg_match('/os/i', $agent)) {
        $os = 'SunOS';
    } else if (preg_match('/ibm/i', $agent) && preg_match('/os/i', $agent)) {
        $os = 'IBM OS/2';
    } else if (preg_match('/Mac/i', $agent)) {
        $os = 'Mac OS';
    } else if (preg_match('/PowerPC/i', $agent)) {
        $os = 'PowerPC';
    } else if (preg_match('/AIX/i', $agent)) {
        $os = 'AIX';
    } else if (preg_match('/HPUX/i', $agent)) {
        $os = 'HPUX';
    } else if (preg_match('/NetBSD/i', $agent)) {
        $os = 'NetBSD';
    } else if (preg_match('/BSD/i', $agent)) {
        $os = 'BSD';
    } else if (preg_match('/OSF1/i', $agent)) {
        $os = 'OSF1';
    } else if (preg_match('/IRIX/i', $agent)) {
        $os = 'IRIX';
    } else if (preg_match('/FreeBSD/i', $agent)) {
        $os = 'FreeBSD';
    } else if (preg_match('/teleport/i', $agent)) {
        $os = 'teleport';
    } else if (preg_match('/flashget/i', $agent)) {
        $os = 'flashget';
    } else if (preg_match('/webzip/i', $agent)) {
        $os = 'webzip';
    } else if (preg_match('/offline/i', $agent)) {
        $os = 'offline';
    } else {
        $os = 'unknow';
    }
    return $os;
}

/**
 * 传入密码和随机数进行加密
 * @param $pwd 传入密码
 * @param $str  传入随机数
 * @return string 返回加密过后的密码
 */
function inge_encryption_pwd($pwd, $str)
{
    $newStr = md5($pwd . $str);
    $newStr = substr($newStr, 6);
    $newStr = md5($newStr . $str);
    $newStr = crypt($newStr, $str);
    return $newStr;
}

/**
 * 获取随机字符
 * @param $len 需要的长度
 * @param type 为1 则大小写字母都可以  为0则为数字
 * @return string 返回获取到的随机字符串
 *
 */
function inge_get_random_str($len = 10, $type = '1')
{
    $str = null;
    if ($type == '1') {
        $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
    } else {
        $strPol = "0123456789";
    }
    $max = strlen($strPol) - 1;
    for ($i = 0; $i < $len; $i++) {
        $str .= $strPol[rand(0, $max)];
    }
    return $str;
}

/**
 * 验证是否是手机号
 * @param $mobilephone
 * @return bool
 */
function inge_ismobile($mobilephone)
{
    if (strlen($mobilephone)==11) {
        return true;
    } else {
        return false;
    }
}

/**
 * 验证是否为邮箱
 * @param  [type] $email [description]
 * @return [type]        [description]
 */
function inge_isemail($email)
{
    $pattern = "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i";
//    if (preg_match("^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+", $email)) {
    if (preg_match($pattern, $email)) {
        return true;
    } else {
        return false;
    }
}

/**
 * 二维数组根据某个字段排序
 * @param  [type] $arrUsers [description] 需要排序的数组
 * @param [type] $field     [description] 按哪个字段排序
 * @param [type] $way       [description] 排序顺序标志 SORT_DESC 降序；SORT_ASC 升序
 */
function inge_sortArrByField($arrUsers, $field, $way = 'SORT_ASC')
{
    $sort = array(
        'direction' => $way,
        'field'     => $field,
    );
    $arrSort = array();
    foreach ($arrUsers as $uniqid => $row) {
        foreach ($row as $key => $value) {
            $arrSort[$key][$uniqid] = $value;
        }
    }
    if ($sort['direction']) {
        array_multisort($arrSort[$sort['field']], constant($sort['direction']), $arrUsers);
    }

    return $arrUsers;
}

/**
 * 返回不含前缀的数据库表数组
 *
 * @author rainfer <81818832@qq.com>
 * @param bool
 * @return array
 */
function db_get_tables($prefix = false)
{
    $db_prefix = config('database.prefix');
    $list      = \think\Db::query('SHOW TABLE STATUS FROM ' . config('database.database'));
    $list      = array_map('array_change_key_case', $list);
    $tables    = array();
    foreach ($list as $k => $v) {
        if (empty($prefix)) {
            if (stripos($v['name'], strtolower(config('database.prefix'))) === 0) {
                $tables[] = strtolower(substr($v['name'], strlen($db_prefix)));
            }
        } else {
            $tables[] = strtolower($v['name']);
        }

    }
    return $tables;
}

/**
 * 递归重组节点信息为多维数组
 * @param array
 * @param int
 * @param string
 * @param string
 * @param string
 * @return array
 */
function node_merge(&$node, $pid = 0, $id_name = 'id', $pid_name = 'pid', $child_name = '_child')
{
    $arr = array();
    foreach ($node as $v) {
        if ($v[$pid_name] == $pid) {
            $v[$child_name] = node_merge($node, $v[$id_name], $id_name, $pid_name, $child_name);
            $arr[]          = $v;
        }
    }
    return $arr;
}
/**
 * 截取待html的文本
 * @author rainfer <81818832@qq.com>
 * @param string $html
 * @param int $max
 * @param string $suffix
 * @return string;
 */
function html_trim($html, $max, $suffix = '...')
{
    $html = trim($html);
    if (strlen($html) <= $max) {
        return $html;
    }
    $non_paired_tags = array('br', 'hr', 'img', 'input', 'param'); // 非成对标签
    $html            = preg_replace('/<img([^>]+)>/i', '', $html);
    $count           = 0; // 有效字符计数(一个HTML实体字符算一个有效字符)
    $tag_status      = 0; // (0:非标签, 1:标签开始, 2:标签名开始, 3:标签名结束)
    $nodes           = array(); // 存放解析出的节点(文本节点:array(0, '文本内容', 'text', 0), 标签节点:array(1, 'tag', 'tag_name', '标签性质:0:非成对标签,1:成对标签的开始标签,2:闭合标签'))
    $segment         = ''; // 文本片段
    $tag_name        = ''; // 标签名
    for ($i = 0; $i < strlen($html); $i++) {
        $char = $html[$i]; // 当前字符
        $segment .= $char; // 保存文本片段
        if ($tag_status == 4) {
            $tag_status = 0;
        }
        if ($tag_status == 0 && $char == '<') {
            // 没有开启标签状态,设置标签开启状态
            $tag_status = 1;
        }
        if ($tag_status == 1 && $char != '<') {
            // 标签状态设置为开启后,用下一个字符来确定是一个标签的开始
            $tag_status = 2; //标签名开始
            $tag_name   = ''; // 清空标签名
            // 确认标签开启,将标签之前保存的字符版本存为文本节点
            $nodes[] = array(0, substr($segment, 0, strlen($segment) - 2), 'text', 0);
            $segment = '<' . $char; // 重置片段,以标签开头
        }
        if ($tag_status == 2) {
            // 提取标签名
            if ($char == ' ' || $char == '>' || $char == "\t") {
                $tag_status = 3; // 标签名结束
            } else {
                $tag_name .= $char; // 增加标签名字符
            }
        }
        if ($tag_status == 3 && $char == '>') {
            $tag_status = 4; // 重置标签状态
            $tag_name   = strtolower($tag_name);
            // 跳过成对标签的闭合标签
            $tag_type = 1;
            if (in_array($tag_name, $non_paired_tags)) {
                // 非成对标签
                $tag_type = 0;
            } elseif ($tag_name[0] == '/') {
                $tag_type = 2;
            }
            // 标签结束,保存标签节点
            $nodes[] = array(1, $segment, $tag_name, $tag_type);
            $segment = ''; // 清空片段
        }
        if ($tag_status == 0) {
            //echo $char.')'.$count."\n";
            if ($char == '&') {
                // 处理HTML实体,10个字符以内碰到';',则认为是一个HTML实体
                for ($e = 1; $e <= 10; $e++) {
                    if ($html[$i + $e] == ';') {
                        $segment .= substr($html, $i + 1, $e); // 保存实体
                        $i += $e; // 跳过实体字符所占长度
                        break;
                    }
                }
            } else {
                // 非标签情况下检查有效文本
                $char_code = ord($char); // 字符编码
                if ($char_code >= 224) // 三字节字符
                {
                    $segment .= $html[$i + 1] . $html[$i + 2]; // 保存字符
                    $i += 2; // 跳过下2个字符的长度
                } elseif ($char_code >= 129) // 双字节字符
                {
                    $segment .= $html[$i + 1];
                    $i += 1; // 跳过下一个字符的长度
                }
            }
            $count++;
            if ($count == $max) {
                $nodes[] = array(0, $segment . $suffix, 'text', 0);
                break;
            }
        }
    }
    $html           = '';
    $tag_open_stack = array(); // 成对标签的开始标签栈
    for ($i = 0; $i < count($nodes); $i++) {
        $node = $nodes[$i];
        if ($node[3] == 1) {
            array_push($tag_open_stack, $node[2]); // 开始标签入栈
        } elseif ($node[3] == 2) {
            array_pop($tag_open_stack); // 碰到一个结束标签,出栈一个开始标签
        }
        $html .= $node[1];
    }
    while ($tag_name = array_pop($tag_open_stack)) // 用剩下的未出栈的开始标签补齐未闭合的成对标签
    {
        $html .= '</' . $tag_name . '>';
    }
    return $html;
}

/**
 * 货币转换
 * @param float
 * @return string
 */
function long_currency($long)
{
    return sprintf('%d.%02d', intval($long / 100), intval($long % 100));
}
/**
 * 货币转换
 * @param string
 * @return float
 */
function currency_long($currency)
{
    $s = explode('.', trim($currency));
    switch (count($s)) {
        case 1:
            return $s[0] * 100;
        case 2:
            if (strlen($s[1]) == 1) {
                $s[1] .= '0';
            } else if (strlen($s[1]) > 2) {
                $s[1] = substr($s[1], 0, 2);
            }
            return $s[0] * 100 + $s[1];
    }
    return 0;
}
/**
 * 设置全局配置到文件
 *
 * @param $key
 * @param $value
 * @return boolean
 */
function sys_config_setbykey($key, $value)
{
    $file = ROOT_PATH . 'data/conf/config.php';
    $cfg  = array();
    if (file_exists($file)) {
        $cfg = include $file;
    }
    $item = explode('.', $key);
    switch (count($item)) {
        case 1:
            $cfg[$item[0]] = $value;
            break;
        case 2:
            $cfg[$item[0]][$item[1]] = $value;
            break;
    }
    return file_put_contents($file, "<?php\nreturn " . var_export($cfg, true) . ";");
}
/**
 * 设置全局配置到文件
 *
 * @param array
 * @return boolean
 */
function sys_config_setbyarr($data)
{
    $file = ROOT_PATH . 'data/conf/config.php';
    if (file_exists($file)) {
        $configs = include $file;
    } else {
        $configs = array();
    }
    $configs = array_merge($configs, $data);
    return file_put_contents($file, "<?php\treturn " . var_export($configs, true) . ";");
}
/**
 * 获取全局配置
 *
 * @param $key
 * @return array|null
 */
function sys_config_get($key)
{
    $file = ROOT_PATH . 'data/conf/config.php';
    $cfg  = array();
    if (file_exists($file)) {
        $cfg = (include $file);
    }
    return isset($cfg[$key]) ? $cfg[$key] : null;
}
/**
 * 列出本地目录的文件
 * @author rainfer <81818832@qq.com>
 * @param string $path
 * @param string $pattern
 * @return array
 */
function list_file($path, $pattern = '*')
{
    if (strpos($pattern, '|') !== false) {
        $patterns = explode('|', $pattern);
    } else {
        $patterns[0] = $pattern;
    }
    $i   = 0;
    $dir = array();
    if (is_dir($path)) {
        $path = rtrim($path, '/') . '/';
    }
    foreach ($patterns as $pattern) {
        $list = glob($path . $pattern);
        if ($list !== false) {
            foreach ($list as $file) {
                $dir[$i]['filename']   = basename($file);
                $dir[$i]['path']       = dirname($file);
                $dir[$i]['pathname']   = realpath($file);
                $dir[$i]['owner']      = fileowner($file);
                $dir[$i]['perms']      = substr(base_convert(fileperms($file), 10, 8), -4);
                $dir[$i]['atime']      = fileatime($file);
                $dir[$i]['ctime']      = filectime($file);
                $dir[$i]['mtime']      = filemtime($file);
                $dir[$i]['size']       = filesize($file);
                $dir[$i]['type']       = filetype($file);
                $dir[$i]['ext']        = is_file($file) ? strtolower(substr(strrchr(basename($file), '.'), 1)) : '';
                $dir[$i]['isDir']      = is_dir($file);
                $dir[$i]['isFile']     = is_file($file);
                $dir[$i]['isLink']     = is_link($file);
                $dir[$i]['isReadable'] = is_readable($file);
                $dir[$i]['isWritable'] = is_writable($file);
                $i++;
            }
        }
    }
    $cmp_func = create_function('$a,$b', '
        if( ($a["isDir"] && $b["isDir"]) || (!$a["isDir"] && !$b["isDir"]) ){
            return  $a["filename"]>$b["filename"]?1:-1;
        }else{
            if($a["isDir"]){
                return -1;
            }else if($b["isDir"]){
                return 1;
            }
            if($a["filename"]  ==  $b["filename"])  return  0;
            return  $a["filename"]>$b["filename"]?-1:1;
        }
        ');
    usort($dir, $cmp_func);
    return $dir;
}
/**
 * 删除文件夹
 * @author rainfer <81818832@qq.com>
 * @param string
 * @param int
 */
function remove_dir($dir, $time_thres = -1)
{
    foreach (list_file($dir) as $f) {
        if ($f['isDir']) {
            remove_dir($f['pathname'] . '/');
        } else if ($f['isFile'] && $f['filename']) {
            if ($time_thres == -1 || $f['mtime'] < $time_thres) {
                @unlink($f['pathname']);
            }
        }
    }
}
/**
 * 通过用户id获取用户名
 */
function get_username_byid($id)
{
    $res = Db::table('__USER__')->where('user_id', $id)->find();
    if ($res) {
        return $res['user_name'];
    } else {
        return '';
    }
}
/**
 * 通用列表排序函数
 * @param  string $value [description]
 * @return [type]        [description]
 */
function listorder($idtitle, $id, $order, $modelobject)
{
    foreach ($id as $key => $value) {
        $list[] = [$idtitle => $value, 'listorder' => $order[$key]];
    }
    $res = $modelobject->saveAll($list);
    return $res;
}
/**
 * 根据ID获取Term信息 传入$field参数，获取指定字段
 * @param  [type] $id   [description]
 * @param  string $field [description]
 * @return [type]       [description]
 */
function get_terminfo_by_newid($id, $field = '')
{
    $res = Loader::model('Terms')->getTermForObjectId($id);
    if ($res) {
        $res = Loader::model('Terms')->where('term_id', $res['term_id'])->find();
        if ($res) {
            if ($field == '') {
                return $res;
            } else {
                return $res[$field];
            }
        }
    }
    return '';
}

function numinput_to_num($str)
{
    return $string = str_replace(',', '', $str);
}

/**
 * 传入用户id获取等级信息
 * @param  [type] $uid [description]
 * @return [type]      [description]
 */
function store_get_level_by_uid($uid)
{
    $map['user_id'] = $uid;
    $level_id       = Db::table('__USER__')->where($map)->value('level');
    $level_data     = Db::table('__USER_LEVEL__')->where('level_id', $level_id)->find();
    if (count($level_data)) {
        return $level_data;
    } else {
        return 0;
    }
}

/**
 * 传入用户id和amount获取等级
 * @param  [type] $uid    [description]
 * @param  [type] $amount [description]
 * @return [type]         [description]
 */
function store_get_level($uid, $amount)
{
    $map['user_id'] = $uid;
    $level_id       = Db::table('__USER__')->where($map)->value('level');
    $level_name     = Db::table('__USER_LEVEL__')->where('level_id', $level_id)->find();
    if ($level_name) {
        return $level_name;
    } else {
        return 0;
    }
}

/**
 * 提升用户总消费额
 * @return [type] [description]
 */
function user_inc_amount($uid, $amo)
{
    $map['user_id'] = $uid;
    $res            = Db::table('__USER__')->where($map)->setInc('total_amount', $amo);
    if ($res) {
        return 1;
    } else {
        return 0;
    }
}

/**
 * 降低用户总消费额
 * @return [type] [description]
 */
function user_dec_amount($uid, $amo)
{
    $map['user_id'] = $uid;
    $res            = Db::table('__USER__')->where($map)->setDec('total_amount', $amo);
    if ($res) {
        return 1;
    } else {
        return 0;
    }
}

/**
 * 获取option表指定配置
 * @date: 2017年3月31日 下午1:54:45
 * @author: 姚荣
 * @param: $name
 * @return:array
 * v1 无数据加载错误 修复：Thans
 */
function get_options($name)
{
    $res = Db::table('__OPTIONS__')
        ->where('option_name', $name . '_options')
        ->column('option_value');
    if ($res) {
        return json_decode($res['0'], true);
    } else {
        return false;
    }
}
/**
 * 获取site指定配置
 * @date: 2017年3月31日 下午1:59:49
 * @author: 姚荣
 * @return:array
 */
function get_site_options()
{
    return $res = get_options('site');
}

/**
 * 获取seo指定配置
 * @date: 2017年3月31日 下午1:59:49
 * @author: 姚荣
 * @return:array
 */
function get_seo_options()
{
    return $res = get_options('seo');
}

/**
 * 获取seo指定配置
 * @date: 2017年3月31日 下午1:59:49
 * @author: 姚荣
 * @return:array
 */
function get_oss_options()
{
    return $res = get_options('oss');
}
/**
 * 获取商品一级分类
 * @return [type] [description]
 */
function get_goods_firstcat()
{
    return Loader::model('GoodsCategory')->getFirstCat();
}

/**
 * 生成订单号
 * @return string
 */
function shop_create_orderid($userinfo){
    return date('YmdHis').inge_get_random_str(6,0).$userinfo['m_id'];
}



/**
 * 调用系统的API接口方法（静态方法）
 * api('User/getName','id=5'); 调用公共模块的User接口的getName方法
 * api('Admin/User/getName','id=5');  调用Admin模块的User接口
 * @param  string  $name 格式 [模块名]/接口名/方法名
 * @param  array|string  $vars 参数
 */
function api($name,$vars=array()){
    $array     = explode('/',$name);
    $method    = array_pop($array);
    $classname = array_pop($array);
    $module    = $array? array_pop($array) : 'common';
    $callback  = 'app\\'.$module.'\\Api\\'.$classname.'Api::'.$method;
    dump($callback);exit;
    if(is_string($vars)) {
        parse_str($vars,$vars);
    }
    return call_user_func_array($callback,$vars);
}





//获取IP
function getIP() {
    if (getenv('HTTP_CLIENT_IP')) {
        $ip = getenv('HTTP_CLIENT_IP');
    }
    elseif (getenv('HTTP_X_FORWARDED_FOR')) {
        $ip = getenv('HTTP_X_FORWARDED_FOR');
    }
    elseif (getenv('HTTP_X_FORWARDED')) {
        $ip = getenv('HTTP_X_FORWARDED');
    }
    elseif (getenv('HTTP_FORWARDED_FOR')) {
        $ip = getenv('HTTP_FORWARDED_FOR');

    }
    elseif (getenv('HTTP_FORWARDED')) {
        $ip = getenv('HTTP_FORWARDED');
    }
    else {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}


/**
 * 记录日志
 * @param  [type] $uid         [用户id]
 * @param  [type] $username    [用户名]
 * @param  [type] $description [描述]
 * @param  [type] $status      [状态]
 * @return [type]              [description]
 */
function writelog($uid,$username,$description,$status,$dbname)
{
    $data['admin_id'] = $uid;
    $data['admin_name'] = $username;
    $data['description'] = $description;
    $data['status'] = $status;
    $data['ip'] = request()->ip();
    $data['add_time'] = time();
    $log = Db::name($dbname)->insert($data);
}


/**
 * 生成密码
 * @param  [type] $password      [密码]
 */

function setPassword($password){
    if($password){
        $data = array();
        $chars = "0123456789";
        $str = "";
        for ($i = 0; $i < 8; $i ++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        $data['strict'] = $str;
        $data['password'] = md5(md5($password).$data['strict']);
        return $data;
    }else{
        return false;
    }
}


/**
 * 整理菜单树方法
 * @param $param
 * @return array
 */
function prepareMenu($param)
{
    $parent = []; //父类
    $child = [];  //子类

    foreach($param as $key=>$vo){

        if($vo['pid'] == 0){
            $vo['href'] = '#';
            $parent[] = $vo;
        }else{
            $vo['href'] = url($vo['url']); //跳转地址
            $child[] = $vo;
        }
    }

    foreach($parent as $key=>$vo){
        foreach($child as $k=>$v){

            if($v['pid'] == $vo['id']){
                $parent[$key]['child'][] = $v;
            }
        }
    }
    unset($child);
    return $parent;
}

/**
 * @param $timestamp
 * @return false|string
 *    时间戳转换
 * @date: 2017年8月28日 下午14:10:00
 * @author: 杨胜飞
 */
function get_time($timestamp)
{
    return date('Y-m-d H:i:s',$timestamp);
}

/**
 * 公共发送邮件函数
 * @author bg
 * @param $desc_content     邮件内容
 * @param $toemail          收件人邮箱
 * @param $title            邮箱标题
 * @return 0/1
 */
function sendEmail($desc_content, $toemail,$title){
    $smtpConfig = config('smtp');
    if($smtpConfig){
        $mail = new PHPMailer();
        $mail->SMTPDebug = 0;
        $mail->isSMTP();// 使用SMTP服务
        $mail->CharSet = "utf8";// 编码格式为utf8，不设置编码的话，中文会出现乱码
        $mail->Host = $smtpConfig->MAIL_SMTP;// 发送方的SMTP服务器地址
        $mail->SMTPAuth = true;// 是否使用身份验证
        $mail->From = $smtpConfig->MAIL_ADDRESS;
        $mail->Username = $smtpConfig->MAIL_LOGINNAME;// 发送方的163邮箱用户名，就是你申请163的SMTP服务使用的163邮箱</span><span style="color:#333333;">
        $mail->Password = $smtpConfig->MAIL_PASSWORD;// 发送方的邮箱密码，注意用163邮箱这里填写的是“客户端授权密码”而不是邮箱的登录密码！</span><span style="color:#333333;">
        if(isset($smtpConfig->MAIL_SECURE)){
            $mail->SMTPSecure = "ssl";// 使用ssl协议方式</span><span style="color:#333333;">

        }
        $mail->Port = $smtpConfig->MAIL_PORT;// 163邮箱的ssl协议方式端口号是465/994
        $mail->setFrom("","Mailer");// 设置发件人信息，如邮件格式说明中的发件人，这里会显示为Mailer(xxxx@163.com），Mailer是当做名字显示
        $mail->addAddress($toemail,$toemail);// 设置收件人信息，如邮件格式说明中的收件人，这里会显示为Liang(yyyy@163.com)
        $mail->addReplyTo("","Reply");// 设置回复人信息，指的是收件人收到邮件后，如果要回复，回复邮件将发送到的邮箱地址
        //$mail->addCC("xxx@163.com");// 设置邮件抄送人，可以只写地址，上述的设置也可以只写地址(这个人也能收到邮件)
        //$mail->addBCC("xxx@163.com");// 设置秘密抄送人(这个人也能收到邮件)
        //$mail->addAttachment("bug0.jpg");// 添加附件
        $mail->Subject = $title;// 邮件标题
        $mail->Body = $desc_content;// 邮件正文
        //$mail->AltBody = "This is the plain text纯文本";// 这个是设置纯文本方式显示的正文内容，如果不支持Html方式，就会用到这个，基本无用
        if(!$mail->send()){// 发送邮件
            return $mail->ErrorInfo;
        }else{
            return 1;
        }
    }else{
        return 0;
    }
}

/**
 * 公共发送短信函数
 * @author bg
 * @param $phone     手机号码
 * @param $content   内容
 * @return 0/1/-1;
 */
function sendSms($phone, $content){
    $smsConfig = config('sms');
    if($smsConfig){
        //配置参数
        $sms_config['uid']=$smsConfig->uid;
        $sms_config['content']=$smsConfig->sign_name;
        $sms_config['passwd']=$smsConfig->passwd;
        $content = $content . "。【" . $sms_config['content'] . "】";
        $gateway = "http://sms.bamikeji.com:8890/mtPort/mt/normal/send?uid=" . $sms_config['uid'] . "&passwd=" . md5($sms_config['passwd']) . "&phonelist=" . $phone . "&content=" . $content;
        $result = file_get_contents($gateway);
        $ret = json_decode($result, true);
        if($ret['success']){
            return 1;
        }else{
            return 0;
        }
    }else{
        //不启用短信
        return -1;
    }
}

/**
 * Warning提示信息
 * @param string $type 提示类型 默认支持success, error, info
 * @param string $msg 提示信息
 * @param string $url 跳转的URL地址
 * @return void
 */
function alert($type='info', $msg='', $url='') {
    //多行URL地址支持
    $url        = str_replace(array("\n", "\r"), '', $url);
    $alert = unserialize(stripslashes(cookie('alert')));
    if (!empty($msg)) {
        $alert[$type][] = $msg;
        cookie('alert', serialize($alert));
    }
    if (!empty($url)) {
        if (!headers_sent()) {
            // redirect
            header('Location: ' . $url);
            exit();
        } else {
            $str    = "<meta http-equiv='Refresh' content='0;URL={$url}'>";
            exit($str);
        }
    }

    return $alert;
}
function parseAlert() {
    $alert = unserialize(stripslashes(cookie('alert')));
    cookie('alert', null);

    return $alert;
}



/**
 * 格式化字节大小
 * @param  number $size      字节数
 * @param  string $delimiter 数字和单位分隔符
 * @return string            格式化后的带单位的大小
 */
function format_bytes($size, $delimiter = '') {
    $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
    for ($i = 0; $size >= 1024 && $i < 5; $i++) {
        $size /= 1024;
    }
    return $size . $delimiter . $units[$i];
}

/**
 * 菜单栏路由处理
 * @param unknown $string
 * @return boolean
 */

function UrlProcessing($string){
    if(empty($string)){
        return false;
    }else{
        $string = strtolower($string);
        $string = str_replace('_','',$string);
        return $string;
    }
}

/*
 * URL装数组
 */
function UrlTrans($url){
    $urlArray = explode('/',$url);
    return strtolower($urlArray[1]);
}



/**
 * 字符串截取，支持中文和其他编码
 * @static
 * @access public
 * @param string $str 需要转换的字符串
 * @param string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param string $suffix 截断显示字符
 * @return string
 */
function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true) {
    if(function_exists("mb_substr"))
        $slice = mb_substr($str, $start, $length, $charset);
    elseif(function_exists('iconv_substr')) {
        $slice = iconv_substr($str,$start,$length,$charset);
        if(false === $slice) {
            $slice = '';
        }
    }else{
        $re['utf-8']   = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk']    = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5']   = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("",array_slice($match[0], $start, $length));
    }
    return $suffix ? $slice.'****' : $slice;
}

/*
 *  生成员工编号（6位）
 *  @author ligang
 *  @param int  $time
 *  @return int
 */
function EmployeeNumber(){
    $checkEmployeeNumber = Db::name('personnel_number')->max('personnel_number');
    if (!$checkEmployeeNumber){
        $number = 100001;
        return $number;
    }else{
        return $checkEmployeeNumber+1;
    }
}


/*
 * 身份证校验、并截取生日(15 or 18)
 * @ligang
 * @return  bool
*/
function checkIdCard($idCard){
    $result = preg_match('/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X|x)$/',$idCard);
    if ($result){
        return true;
    }else{
        return false;
    }
}

/*
 *  根据身份证获取生日
 *  @author ligang
 *  @return int
 */
function getBirthday($idCard){
    if (strlen($idCard) == 15){
        $birthday = substr($idCard,4,4)."-".substr($idCard,8,2)."-".substr($idCard,10,2);
    }else{
        $birthday = substr($idCard,6,4)."-".substr($idCard,10,2)."-".substr($idCard,12,2);
    }
    return strtotime($birthday);
}

/*
 *  随机生成设备编号
 *  @author ligang
 *  @return int
 */
function randEquipmentsNumber(){
    $str = '';
    for ($i=1;$i<=10;$i++){
        $str .= mt_rand(0,9);
    }
    $checkNumber = Db::name('contract_equipment')->where(['equipments_number'=>$str])->find();
    if (!$checkNumber){
        return $str;
    }
    randEquipmentsNumber();
}

/**
 * 密码比较方法,所有涉及密码比较的地方都用这个方法
 * @param string $password 要比较的密码
 * @param string $passwordInDb 数据库保存的已经加密过的密码
 * @return boolean 密码相同，返回true
 */
function cms_compare_password($password, $passwordInDb,$slat)
{
    if($passwordInDb !== md5(md5($password).$slat)){
        return false;
    }
    return true;
}

/**
 * 生成密码
 * @param string $password 要比较的密码
 * @param string $slat 数据库保存的已经加密过的密码
 * @return string 密码相同，返回string
 */
function compare_password($password,$slat)
{
    return md5(md5($password).$slat);
}

/**
 * curl get 请求
 * @param $url
 * @return mixed
 */
function cms_curl_get($url)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FAILONERROR, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    $SSL = substr($url, 0, 8) == "https://" ? true : false;
    if ($SSL) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 检查证书中是否设置域名
    }
    $content = curl_exec($ch);
    return $content;
}

/**
 * @param $url
 * @param $post_data
 * @return mixed
 *        使用curl发送post请求
 */
function post_request($url, $post_data){
    // 使用post发送请求
    $curlObj = curl_init();
    curl_setopt($curlObj, CURLOPT_URL, $url);
    curl_setopt($curlObj, CURLOPT_RETURNTRANSFER, 1);
    // post数据
    curl_setopt($curlObj, CURLOPT_POST, 1);
    // post的变量
    curl_setopt($curlObj, CURLOPT_POSTFIELDS, $post_data);
    $output = curl_exec($curlObj);
    if($output === FALSE ){
        return "CURL Error:".curl_error($curlObj);
    }
    // 发送完毕后 关闭curl资源
    curl_close($curlObj);
    // 返回获取的数据
    return $output;
}


/**
 * 生成用户 token
 * @param $userId
 * @param $deviceType
 * @return string 用户 token
 */
function cms_generate_user_token($userId, $deviceType)
{
    $userTokenQuery = Db::name("user_token")
        ->where('user_id', $userId)
        ->where('device_type', $deviceType);
    $findUserToken  = $userTokenQuery->find();
    $currentTime    = time();
    $expireTime     = $currentTime + 24 * 3600 * 180;
    $token          = md5(uniqid()) . md5(uniqid());
    if (empty($findUserToken)) {
        Db::name("user_token")->insert([
            'token'       => $token,
            'user_id'     => $userId,
            'expire_time' => $expireTime,
            'create_time' => $currentTime,
            'device_type' => $deviceType
        ]);
    } else {
        Db::name("user_token")
            ->where('user_id', $userId)
            ->where('device_type', $deviceType)
            ->update([
                'token'       => $token,
                'expire_time' => $expireTime,
                'create_time' => $currentTime
            ]);
    }

    return $token;
}

/**
 * @return int|mixed
 *    生成工单编号（10位）
 *      YSF
 */
function workOrderNumber(){
    $checkWorkOrderNumber = Db::name('work_order')->max('order_number');
    if (!$checkWorkOrderNumber){
        $number = 1000000001;
        return $number;
    }else{
        return $checkWorkOrderNumber+1;
    }
}

/**
 * 递归将数组中所有 null 替换成 ''
 * @return arr
 * @author luo
 */
function unsetnullArr($arr)
{

    $narr = array();
    while(list($key, $val) = each($arr)){
        if (is_array($val)){
            $val = $this->unsetnullArr($val);
            count($val)==0 || $narr[$key] = $val;
        }
        else
        {
            $val === null?$narr[$key] = '':$narr[$key] = $val;
        }
    }
    return $narr;
}

/**
 * 递归将数组中所有 null  '' 删除
 * @return arr
 * @author luo
 */
function array_remove_empty($arr)
{
    $narr                  = array();
    while(list($key, $val) = each($arr)){
        if (is_array($val)){
            $val                   = $this->array_remove_empty($val);
            count($val)            ==0 || $narr[$key] = $val;
        }
        else
        {
            if (trim($val)         != ""){
                $narr[$key]            = $val;
            }
        }
    }
    unset($arr);
    return $narr;
}




